home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / info-service / gopher / incoming / gopher2nntp < prev    next >
Encoding:
Text File  |  1992-07-24  |  5.9 KB  |  295 lines

  1.  
  2. #!/usr/local/bin/perl
  3. #
  4. # switch to nobody if we are root
  5. ($<,$>) = (-2,-2) unless $>;
  6.  
  7. require 'getopts.pl';
  8.  
  9. #
  10. # Simple gopher2nntp server. You can change the following variables.
  11. # nntp_port is hardcoded here since this is a stateless server and
  12. # no sense in reading it from /etc/services every time...
  13. #
  14. # A server that sticks around might be better...
  15. #
  16. # Note: The NNTP daemon must accept the XHDR command.
  17. #
  18. #
  19. # You should run "gopher2nntp -g" from cron to generate the groups 
  20. # file. If you don't generate the groups file then this server will
  21. # grab it from the NNTP server, but thats a waste of time. 
  22. #
  23. #
  24.   $nntp_server = "leland.stanford.edu";
  25.   $nntp_port   = 119;
  26.   $nntp_groups = "/usr/local/etc/newsgroups.gopher"; # could be active file
  27.  
  28.   @nntp_acl=(
  29. #     ipaddress  group    access + = allow, - = deny    
  30.      '^36\.      .*       +',
  31.      '.*         ^clari   -',
  32.      '.*         .*       +'
  33.   );
  34.  
  35. #
  36. # Commands this server responds to:
  37. # ""                         -> list top level groups
  38. # ls $group                  -> list group's articles and sub-groups
  39. # article $group $number     -> get 1 article
  40. # sorry                      -> send sorry message
  41. #
  42.  
  43. $port=&my_port();         # port this script is running on 
  44. chop($host = `hostname`);
  45.  
  46. &Getopts('nrdga:s:');
  47.  
  48. if ($errs || $#ARGV!=-1) {
  49.  
  50. print<<EOF;
  51.  
  52.  Usage: $0 [-s server] [-a active_file] [-n] [-g] [-d] [-r]
  53.  -s server      NNTP server to contact
  54.  -a file        Active file to use
  55.  -n             Don't use active file
  56.  -g             generate new active file
  57.  -d             turn on debug (when typing commands from a tty)
  58.  -r             list articles in reverse order
  59. EOF
  60. exit;
  61.  
  62. }
  63.  
  64. $nntp_server = $opt_s if (defined($opt_s));
  65. $nntp_port = $opt_p if (defined($opt_p));
  66. $nntp_groups = $opt_a if (defined($opt_a));
  67.  
  68. &create_groups($opt_g) if defined($opt_g);
  69.  
  70.   $_ = <STDIN>; s/\r//; s/\n//;
  71.  
  72.   &do_ls("") if /^$/;
  73.   &do_ls($1) if /^ls\s+(.*)/i;
  74.   &do_article($1,$2) if /^article\s+(\S+)\s+(\d+)/i;
  75.   &do_sorry if /^sorry$/;
  76.   &reply("3Unknown command!");
  77.   exit;
  78.  
  79. sub do_article {
  80.   local($group,$number) = @_;
  81.  
  82.   if (&check_access($group) eq '-')  { 
  83.       &do_sorry;
  84.       &reply("."); 
  85.       exit; 
  86.   }
  87.  
  88.   &open_nntp;
  89.  
  90.   &send("GROUP $group");
  91.   $_ = &recv;
  92.   &death if !/^211/;
  93.  
  94.   &send("ARTICLE $number");
  95.   $_ = &recv;
  96.   &death if !/^220/;
  97.  
  98.   while(<SERVER>) {
  99.     print;
  100.     last if /^\.\r\n$/;
  101.   }
  102.  
  103.   &close_nntp;
  104.   exit;
  105. }
  106.  
  107. sub list_group {
  108.   local($group) = @_;
  109.  
  110.   &send("GROUP $group");
  111.   $_ = &recv;
  112.   &death if !/^211/;
  113.  
  114.   ($n,$f,$l) = /211\s+(\d+)\s+(\d+)\s+(\d+)/;
  115.  
  116.   &send("XHDR Subject $f-$l");
  117.   $_ = &recv;
  118.   &death if !/^221/;
  119.  
  120.   while(<SERVER>) {
  121.     chop; chop;
  122.     last if /^\.$/;
  123.     ($article,$subject) = /^(\d+)\s+(.*)/;
  124.     $subject =~ s/\t/ /g; # just in case!
  125.     if (defined($opt_r)) {
  126.        push(@reply,"0$subject\tarticle $group $article\t$host\t$port");
  127.     } else {
  128.        &reply("0$subject\tarticle $group $article\t$host\t$port");
  129.     }
  130.   }
  131.  
  132.   if (defined($opt_r)) { 
  133.     for ($i=$#reply; $i!= -1; $i--) { &reply($reply[$i]); } 
  134.   }
  135.  
  136.   &reply(".");
  137.   &close_nntp;
  138.   exit;
  139. }
  140.  
  141.  
  142. sub do_ls {
  143.   local($prefix) = @_;
  144.  
  145.   if (&check_access($prefix) eq '-') {
  146.       &reply("0Sorry! No no access off of campus!\tsorry\t$host\t$port");
  147.       &reply("."); 
  148.       exit; 
  149.   }
  150.  
  151.   &open_nntp;
  152.   &get_groups;
  153.  
  154.   foreach ( sort @groups) {
  155.     if ($_ eq $prefix) { $do_list_group = $_; }
  156.     elsif (/^$prefix\.([^.]*)\.?/) {
  157.          $leaf=$1;
  158.          $save{"$prefix.$leaf"} = "1$leaf\tls $prefix.$leaf\t$host\t$port";
  159.     }
  160.     elsif ($prefix eq '' && /([^.]*)/) {
  161.          $save{"$1"} = "1$1\tls $1\t$host\t$port";
  162.     }
  163.   }
  164.  
  165.   foreach ( sort keys %save) { &reply($save{$_}); }
  166.   &list_group($do_list_group) if ($do_list_group);
  167.  
  168.   &reply(".");
  169.   &close_nntp;
  170.   exit;
  171. }
  172.  
  173. sub open_nntp {
  174.   local($_);
  175.   &open_server($nntp_server,$nntp_port);
  176.   $_ = &recv;
  177.   &death if !/^2/;
  178. }
  179.  
  180. sub close_nntp {
  181.   &send("QUIT");
  182.   close(SERVER);
  183. }
  184.  
  185. sub my_port {
  186.    return -1 if (-t STDIN);
  187.    $sockaddr = 'S n a4 x8';
  188.    $mysockaddr = getsockname(STDIN);
  189.    ($myfamily,$myport,$myaddr) = unpack($sockaddr,$mysockaddr);
  190.    return $myport;
  191. }
  192.  
  193. sub open_server {
  194.  
  195.  local($server,$port) = @_;
  196.  $sockaddr = 'S n a4 x8';
  197.  (($name, $aliases, $type, $len, $saddr) = gethostbyname($server))||&death;
  198.  $sin = pack($sockaddr, 2, $port, $saddr);
  199.  socket(SERVER, 2, 1, 0) || &death;
  200.  connect(SERVER, $sin)   || &death;
  201.  select(SERVER); $| = 1; select(STDOUT); $| = 1;
  202.  
  203. }
  204.  
  205. sub send     { 
  206.      print "send -> |$_[0]|\n" if (defined($opt_d));
  207.      print SERVER "$_[0]\r\n"; 
  208. }
  209.  
  210. sub recv { 
  211.    local ($_); 
  212.    $_= <SERVER>; 
  213.    chop; chop;
  214.    print "recv -> |$_|\n" if (defined($opt_d));
  215.    return $_; 
  216. }
  217.  
  218. sub reply { print "$_[0]\r\n";}
  219. sub death { &reply("."); exit; }
  220.  
  221. sub get_groups {
  222.  if (!defined($opt_n) && open(GROUPS,$nntp_groups)) {
  223.       while(<GROUPS>) {
  224.           chop;
  225.           ($grp) = /^(\S+)/;
  226.           push(@groups,$grp);
  227.       }
  228.       close(GROUPS);
  229.  } else {                  # can't open file, get list from server!
  230.   &load_groups;
  231.  }
  232. }
  233.  
  234. sub load_groups {
  235.  
  236.   &open_nntp;
  237.   &send("LIST");
  238.   $_ = &recv;
  239.   &death if !/^215/;
  240.  
  241.   while(<SERVER>) {
  242.     chop; chop;
  243.     last if /^\.$/;
  244.     s/^(\S+).*/$1/;
  245.     push(@groups,$_);
  246.   }
  247.  
  248. }
  249.  
  250. sub create_groups { 
  251.  
  252.   &load_groups;
  253.  
  254.   open(GROUPS,">$nntp_groups") || die "$nntp_groups: $!";
  255.   foreach (@groups) { print GROUPS "$_\n"; }
  256.   close GROUPS;
  257.  
  258.   &close_nntp;
  259.   exit;
  260. }
  261.  
  262. sub check_access {
  263.    local($group)=@_;
  264.  
  265.    return 1 if (-t STDIN);
  266.    $sockaddr = 'S n a4 x8';
  267.    $mysockaddr = getpeername(STDIN);
  268.    ($ramily,$rport,$raddr) = unpack($sockaddr,$mysockaddr);
  269.    ($a,$b,$c,$d) = unpack('C4',$raddr);
  270.    $ipaddress = "$a.$b.$c.$d";
  271.  
  272.    foreach (@nntp_acl) {
  273.       ($ipacl,$groupacl,$access)=split;
  274.       return $access if  ($ipaddress =~ /$ipacl/) && ($group =~ /$groupacl/);
  275.    }
  276.    return '-'; #default is to restrict access
  277. }
  278.  
  279. sub do_sorry {
  280.  
  281. print<<EOF;
  282.  
  283. Sorry! You have selected information that cannot be delivered off
  284. of campus due to restrictions.
  285.  
  286.    -- The Mole Hole Guardian
  287.  
  288. EOF
  289.  
  290. &reply(".");
  291. exit;
  292.  
  293. }
  294.